package top.yamhk.plugin.demo;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import top.yamhk.agent.ServerMonitorService;
import top.yamhk.agent.entity.dto.Message;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 聊天相关的REST API控制器
 * 提供用户管理、消息发送、在线状态等接口
 *
 * @author YamHK
 */
@Slf4j
@Lazy
@RestController
@RequestMapping("/api/chat")
@ConditionalOnProperty(name = "chat.api.enabled", havingValue = "true", matchIfMissing = true)
@EnableScheduling // 启用定时任务
public class ChatRestApi {

    @Autowired
    private ServerMonitorService serverMonitorService;

    /**
     * 当前在线用户数
     */
    private static final AtomicInteger ONLINE_NUM = new AtomicInteger();

    /**
     * 存储在线用户信息
     */
    private static final ConcurrentHashMap<String, UserInfo> USER_INFOS = new ConcurrentHashMap<>();

    /**
     * 消息历史存储
     */
    private static final List<Message> MESSAGE_HISTORY = Collections.synchronizedList(new ArrayList<>());

    /**
     * 最后一条消息的ID，用于接收方获取增量消息
     */
    private static volatile long LAST_MESSAGE_ID = 0;

    /**
     * 消息历史最大存储数量
     */
    private static final int MAX_HISTORY = 100;

    /**
     * 用户信息类
     */
    public static class UserInfo {
        private String userId;
        private String province;
        private String publicIp;
        private Date lastActivity;
        private String topic; // 添加主题字段
        private Date lastIpUpdate; // 上次更新IP的日期

        public UserInfo(String userId, String province, String publicIp, String topic) {
            this.userId = userId;
            this.province = province;
            this.publicIp = publicIp;
            this.lastActivity = new Date();
            this.topic = topic;
            this.lastIpUpdate = new Date(); // 初始化为当前日期
        }

        // Getters and Setters
        public String getUserId() {
            return userId;
        }

        public void setUserId(String userId) {
            this.userId = userId;
        }

        public String getProvince() {
            return province;
        }

        public void setProvince(String province) {
            this.province = province;
        }

        public String getPublicIp() {
            return publicIp;
        }

        public void setPublicIp(String publicIp) {
            this.publicIp = publicIp;
        }

        public Date getLastActivity() {
            return lastActivity;
        }

        public void setLastActivity(Date lastActivity) {
            this.lastActivity = lastActivity;
        }

        public String getTopic() {
            return topic;
        }

        public void setTopic(String topic) {
            this.topic = topic;
        }

        public Date getLastIpUpdate() {
            return lastIpUpdate;
        }

        public void setLastIpUpdate(Date lastIpUpdate) {
            this.lastIpUpdate = lastIpUpdate;
        }
    }

    /**
     * 检查系统是否满载
     * @return true表示系统满载，false表示正常
     */
    private boolean isSystemOverloaded() {
        return serverMonitorService != null && serverMonitorService.isSystemOverloaded();
    }

    /**
     * 加入聊天室
     */
    @PostMapping(value = "/join", consumes = "application/json")
    public ApiResponse joinChat(@RequestBody JoinRequest request, HttpServletRequest httpRequest) {
        // 检查系统是否满载，仅限制新用户加入
        if (isSystemOverloaded()) {
            //打印在线用户数
            log.warn("当前在线用户数：{}，系统已满载", ONLINE_NUM.get());
            return ApiResponse.error("系统满载，暂不支持新用户加入");
        }
        
        try {
            // 验证必要参数
            if (request.getUserId() == null || request.getUserId().isEmpty()) {
                return ApiResponse.error("用户ID不能为空");
            }

            String topic = request.getTopic();
            if (topic == null || topic.trim().isEmpty() || topic.length() > 50) {
                topic = "default"; // 设置默认主题
            }

            String province = request.getProvince();

            // 获取客户端真实IP地址
            String clientIp = getClientIp(httpRequest);

            // 优先通过IP地址获取省份信息，以确保准确性
            String userProvince = getProvinceFromIp(clientIp);
            // 如果通过IP无法获取有效省份信息，再考虑使用前端提供的数据
            if (("未知".equals(userProvince) || "局域网".equals(userProvince)) &&
                    province != null && !province.isEmpty() && !"未知".equals(province) && !"未知省份".equals(province)) {
                userProvince = province;
            }

            // 更新或创建用户信息
            UserInfo userInfo = USER_INFOS.get(request.getUserId());
            if (userInfo == null) {
                userInfo = new UserInfo(request.getUserId(), userProvince, clientIp, topic);
                USER_INFOS.put(request.getUserId(), userInfo);
                ONLINE_NUM.incrementAndGet();
            } else {
                // 更新用户信息（包括IP和地理位置）
                // 检查是否需要更新IP信息（每天首次访问时更新）
                if (shouldUpdateIpInfo(userInfo.getLastIpUpdate())) {
                    userInfo.setPublicIp(clientIp);
                    userInfo.setProvince(userProvince);
                    userInfo.setLastIpUpdate(new Date());

                    // 如果之前是内网IP，现在获取到公网IP，则强制更新省份信息
                    if (isPrivateIpAddress(userInfo.getPublicIp()) && !isPrivateIpAddress(clientIp)) {
                        String newProvince = getProvinceFromIp(clientIp);
                        if (!"未知".equals(newProvince) && !"局域网".equals(newProvince)) {
                            userInfo.setProvince(newProvince);
                        }
                    }
                }
                userInfo.setLastActivity(new Date());
                userInfo.setTopic(topic); // 更新主题
            }

            log.warn("用户加入聊天室: userId={}, topic={}, province={}, ip={}", request.getUserId(), topic, userProvince, clientIp);
            // 添加更详细的日志
            log.debug("用户详细信息: userId={}, clientIp={}, userProvince={}, topic={}", request.getUserId(), clientIp, userProvince, topic);
            return ApiResponse.ok("加入成功", null);
        } catch (Exception e) {
            log.error("用户加入聊天室失败: userId=" + request.getUserId(), e);
            return ApiResponse.error("加入失败: " + e.getMessage());
        }
    }

    /**
     * 发送消息
     */
    @PostMapping(value = "/send", consumes = "application/json")
    public ApiResponse sendMessage(@RequestBody SendMessageRequest request, HttpServletRequest httpRequest) {
        // 不限制已在线用户发送消息
        
        try {
            // 检查必要参数
            if (request.getUserId() == null || request.getUserId().isEmpty()) {
                return ApiResponse.error("用户ID不能为空");
            }

            if (request.getContent() == null || request.getContent().isEmpty()) {
                return ApiResponse.error("消息内容不能为空");
            }

            if (request.getTopic() == null || request.getTopic().trim().isEmpty() || request.getTopic().length() > 50) {
                return ApiResponse.error("主题不能为空且长度不能超过50个字符");
            }

            // 获取用户信息
            UserInfo userInfo = USER_INFOS.get(request.getUserId());
            String userProvince = "未知";

            // 如果用户已存在，直接使用其省份信息，避免重复获取IP和地理位置
            if (userInfo != null) {
                userProvince = userInfo.getProvince();
            } else {
                // 新用户需要获取客户端真实IP地址
                String clientIp = getClientIp(httpRequest);

                // 优先通过IP地址获取省份信息，以确保准确性
                userProvince = getProvinceFromIp(clientIp);
                // 如果通过IP无法获取有效省份信息，再考虑使用前端提供的数据
                if (("未知".equals(userProvince) || "局域网".equals(userProvince)) &&
                        request.getProvince() != null && !request.getProvince().isEmpty() &&
                        !"未知".equals(request.getProvince()) && !"未知省份".equals(request.getProvince())) {
                    userProvince = request.getProvince();
                }

                // 创建新用户信息
                userInfo = new UserInfo(request.getUserId(), userProvince, clientIp, request.getTopic());
                USER_INFOS.put(request.getUserId(), userInfo);
                ONLINE_NUM.incrementAndGet();
            }

            // 更新用户活动时间
            if (userInfo != null) {
                userInfo.setLastActivity(new Date());
                // 检查是否需要更新IP信息（每天首次访问时更新）
                if (shouldUpdateIpInfo(userInfo.getLastIpUpdate())) {
                    String clientIp = getClientIp(httpRequest);
                    userInfo.setPublicIp(clientIp);
                    userInfo.setLastIpUpdate(new Date());

                    // 如果之前是内网IP，现在获取到公网IP，则强制更新省份信息
                    if (isPrivateIpAddress(userInfo.getPublicIp()) && !isPrivateIpAddress(clientIp)) {
                        String newProvince = getProvinceFromIp(clientIp);
                        if (!"未知".equals(newProvince) && !"局域网".equals(newProvince)) {
                            userInfo.setProvince(newProvince);
                            userProvince = newProvince; // 更新使用的省份信息
                        }
                    }
                }
                // 更新主题
                userInfo.setTopic(request.getTopic());
            }

            // 创建消息对象
            Message message = new Message();
            message.setMsgFrom(request.getUserId());
            message.setContent(request.getContent());
            message.setTopic(request.getTopic());
            message.setProvince(userProvince);
            message.setCreateTime(new Date());

            // 设置消息ID
            long messageId = LAST_MESSAGE_ID + 1;
            LAST_MESSAGE_ID = messageId;
            message.setId(messageId);

            // 添加到消息历史
            MESSAGE_HISTORY.add(message);

            // 保持消息历史在限制范围内
            if (MESSAGE_HISTORY.size() > MAX_HISTORY) {
                synchronized (MESSAGE_HISTORY) {
                    while (MESSAGE_HISTORY.size() > MAX_HISTORY) {
                        MESSAGE_HISTORY.remove(0);
                    }
                }
            }

            log.info("消息发送成功: messageId={}, userId={}, topic={}, content={}",
                    messageId, request.getUserId(), request.getTopic(), request.getContent());
            // 添加更详细的日志
            log.debug("消息详细信息: messageId={}, userId={}, topic={}, content={}, userProvince={}",
                    messageId, request.getUserId(), request.getTopic(), request.getContent(), userProvince);

            return ApiResponse.ok("发送成功", null);
        } catch (Exception e) {
            log.error("消息发送失败: ", e);
            return ApiResponse.error("发送失败: " + e.getMessage());
        }
    }

    /**
     * 获取在线用户列表接口
     */
    @GetMapping(value = "/users/online")
    public ApiResponse getOnlineUsers(@RequestParam String topic) {
        try {
            List<UserInfo> onlineUsers = new ArrayList<>();
            
            // 遍历所有用户信息
            for (UserInfo userInfo : USER_INFOS.values()) {
                // 检查用户最近活动时间，如果超过5分钟没有活动，则认为不在线
                long inactiveTime = System.currentTimeMillis() - userInfo.getLastActivity().getTime();
                if (inactiveTime < 5 * 60 * 1000) { // 5分钟内有活动
                    // 检查用户是否在指定主题中
                    if (topic.equals(userInfo.getTopic())) {
                        onlineUsers.add(userInfo);
                    }
                } else {
                    // 用户超过5分钟没有活动
                    log.debug("发现不活动用户: userId={}, topic={}, inactiveTime={}ms",
                            userInfo.getUserId(), topic, inactiveTime);
                }
            }
            
            return ApiResponse.ok("获取成功", onlineUsers);
        } catch (Exception e) {
            log.error("获取在线用户列表失败", e);
            return ApiResponse.error("获取在线用户列表失败: " + e.getMessage());
        }
    }

    /**
     * 心跳检测接口，用于更新用户活动时间
     */
    @PostMapping(value = "/heartbeat", consumes = "application/json")
    public ApiResponse heartbeat(@RequestBody HeartbeatRequest request) {
        // 不限制已在线用户发送心跳
        
        try {
            // 验证必要参数
            if (request.getUserId() == null || request.getUserId().isEmpty()) {
                return ApiResponse.error("用户ID不能为空");
            }

            if (request.getTopic() == null || request.getTopic().trim().isEmpty() || request.getTopic().length() > 50) {
                return ApiResponse.error("主题不能为空且长度不能超过50个字符");
            }

            // 更新用户活动时间
            UserInfo userInfo = USER_INFOS.get(request.getUserId());
            if (userInfo != null) {
                userInfo.setLastActivity(new Date());
                log.debug("用户心跳更新: userId={}, topic={}", request.getUserId(), request.getTopic());
            } else {
                log.debug("心跳用户不存在: userId={}, topic={}", request.getUserId(), request.getTopic());
            }

            return ApiResponse.ok("心跳更新成功", null);
        } catch (Exception e) {
            log.error("处理用户心跳失败: userId=" + request.getUserId(), e);
            return ApiResponse.error("心跳处理失败: " + e.getMessage());
        }
    }

    /**
     * 用户离开聊天室
     */
    @PostMapping(value = "/leave", consumes = "application/json")
    public ApiResponse leaveChat(@RequestBody LeaveRequest request) {
        // 不限制已在线用户离开聊天室
        
        try {
            // 验证必要参数
            if (request.getUserId() == null || request.getUserId().isEmpty()) {
                return ApiResponse.error("用户ID不能为空");
            }

            if (request.getTopic() == null || request.getTopic().trim().isEmpty() || request.getTopic().length() > 50) {
                return ApiResponse.error("主题不能为空且长度不能超过50个字符");
            }

            // 从在线用户列表中移除用户
            UserInfo userInfo = USER_INFOS.remove(request.getUserId());
            if (userInfo != null) {
                ONLINE_NUM.decrementAndGet();

                // 创建系统消息通知其他用户
                Message message = new Message();
                message.setMsgFrom("system");
                message.setContent("用户 " + request.getUserId() + " 离开了聊天室");
                message.setTopic(request.getTopic());
                message.setProvince(userInfo.getProvince());
                message.setCreateTime(new Date());

                // 设置消息ID
                long messageId = LAST_MESSAGE_ID + 1;
                LAST_MESSAGE_ID = messageId;
                message.setId(messageId);

                // 添加到消息历史
                MESSAGE_HISTORY.add(message);

                // 保持消息历史在限制范围内
                if (MESSAGE_HISTORY.size() > MAX_HISTORY) {
                    synchronized (MESSAGE_HISTORY) {
                        while (MESSAGE_HISTORY.size() > MAX_HISTORY) {
                            MESSAGE_HISTORY.remove(0);
                        }
                    }
                }

                log.warn("用户离开聊天室: userId={}, topic={}, province={}", request.getUserId(), request.getTopic(), userInfo.getProvince());
            } else {
                log.warn("用户离开聊天室: userId={}, topic={} (用户未在在线列表中)", request.getUserId(), request.getTopic());
            }

            return ApiResponse.ok("离开成功", null);
        } catch (Exception e) {
            log.error("处理用户离开聊天室失败: userId=" + request.getUserId(), e);
            return ApiResponse.error("离开失败: " + e.getMessage());
        }
    }

    /**
     * 是否应该更新IP信息（每天首次访问时更新）
     */
    private boolean shouldUpdateIpInfo(Date lastUpdate) {
        if (lastUpdate == null) {
            return true;
        }

        // 获取今天的开始时间
        Calendar today = Calendar.getInstance();
        today.set(Calendar.HOUR_OF_DAY, 0);
        today.set(Calendar.MINUTE, 0);
        today.set(Calendar.SECOND, 0);
        today.set(Calendar.MILLISECOND, 0);

        // 获取上次更新的日期
        Calendar lastUpdateCal = Calendar.getInstance();
        lastUpdateCal.setTime(lastUpdate);

        // 如果上次更新时间早于今天，则需要更新
        return lastUpdateCal.before(today);
    }

    /**
     * 从IP地址获取省份信息
     */
    private String getProvinceFromIp(String ip) {
        try {
            // 忽略内网IP地址
            if (ip == null) {
                return "未知";
            }

            // 处理可能包含多个IP的情况
            if (ip.contains(",")) {
                String[] ips = ip.split(",");
                // 取第一个IP进行解析
                ip = ips[0].trim();
            }

            // IPv4 私有地址和回环地址
            if (ip.startsWith("127.") || ip.startsWith("10.") || ip.startsWith("192.168.")) {
                return "局域网";
            }

            // IPv6 回环地址和链路本地地址
            if ("0:0:0:0:0:0:0:1".equals(ip) || "::1".equals(ip) || ip.startsWith("fe80")) {
                return "局域网";
            }

            log.info("正在获取IP {} 的地理位置信息", ip);
            String ipInfoJson = HttpUtil.get("http://ip-api.com/json/" + ip + "?lang=zh-CN");
            log.debug("IP {} 的地理位置响应: {}", ip, ipInfoJson);

            if (ipInfoJson != null && !ipInfoJson.isEmpty()) {
                Map<String, Object> ipInfo = JSON.parseObject(ipInfoJson, Map.class);
                if (ipInfo.containsKey("status") && "success".equals(ipInfo.get("status"))) {
                    return (String) ipInfo.getOrDefault("regionName", "未知");
                } else {
                    log.warn("获取IP {} 地理位置信息失败，状态: {}", ip, ipInfo.get("status"));
                }
            } else {
                log.warn("获取IP {} 地理位置信息返回空结果", ip);
            }
        } catch (Exception e) {
            log.error("获取IP省份信息失败: ip=" + ip, e);
        }
        return "未知";
    }

    /**
     * 获取客户端IP地址
     */
    private String getClientIp(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }

        // 处理X-Forwarded-For可能包含多个IP的情况，取第一个公网IP
        if (ip != null && ip.contains(",")) {
            String[] ips = ip.split(",");
            for (String singleIp : ips) {
                singleIp = singleIp.trim();
                // 跳过私有IP地址，返回第一个公网IP
                if (!isPrivateIpAddress(singleIp)) {
                    return singleIp;
                }
            }
            // 如果都是私有IP，返回第一个
            return ips[0].trim();
        }

        return ip;
    }

    /**
     * 是否为内网IP地址
     */
    private boolean isPrivateIpAddress(String ip) {
        if (ip == null || ip.isEmpty()) {
            return true;
        }

        // IPv4 私有地址和回环地址
        if (ip.startsWith("127.") || ip.startsWith("10.") || ip.startsWith("192.168.")) {
            return true;
        }

        // IPv6 回环地址和链路本地地址
        if ("0:0:0:0:0:0:0:1".equals(ip) || "::1".equals(ip) || ip.startsWith("fe80")) {
            return true;
        }

        return false;
    }

    /**
     * 发送消息请求
     */
    public static class SendMessageRequest {
        private String userId;
        private String content;
        private String topic;
        private String province;

        // Getters and Setters
        public String getUserId() {
            return userId;
        }

        public void setUserId(String userId) {
            this.userId = userId;
        }

        public String getContent() {
            return content;
        }

        public void setContent(String content) {
            this.content = content;
        }

        public String getTopic() {
            return topic;
        }

        public void setTopic(String topic) {
            this.topic = topic;
        }

        public String getProvince() {
            return province;
        }

        public void setProvince(String province) {
            this.province = province;
        }
    }

    /**
     * 用户离开请求
     */
    public static class LeaveRequest {
        private String userId;
        private String topic;

        // Getters and Setters
        public String getUserId() {
            return userId;
        }

        public void setUserId(String userId) {
            this.userId = userId;
        }

        public String getTopic() {
            return topic;
        }

        public void setTopic(String topic) {
            this.topic = topic;
        }
    }

    /**
     * 心跳请求
     */
    public static class HeartbeatRequest {
        private String userId;
        private String topic;

        // Getters and Setters
        public String getUserId() {
            return userId;
        }

        public void setUserId(String userId) {
            this.userId = userId;
        }

        public String getTopic() {
            return topic;
        }

        public void setTopic(String topic) {
            this.topic = topic;
        }
    }

    /**
     * 获取新消息接口
     */
    @GetMapping(value = "/messages/new")
    public ApiResponse getNewMessages(@RequestParam String topic, @RequestParam long lastId) {
        // 不限制已在线用户获取新消息
        
        try {
            // 验证topic参数
            if (topic == null || topic.trim().isEmpty() || topic.length() > 50) {
                return ApiResponse.error("主题不能为空且长度不能超过50个字符");
            }

            // 收集ID大于lastId的消息
            List<Message> newMessages = new ArrayList<>();
            for (Message message : MESSAGE_HISTORY) {
                if (message.getTopic().equals(topic) && message.getId() > lastId) {
                    // 过滤掉系统消息（用户上线/下线通知）
                    if (!isSystemNotificationMessage(message)) {
                        newMessages.add(message);
                    }
                }
            }

            log.debug("获取新消息: topic={}, lastId={}, newMessagesCount={}", topic, lastId, newMessages.size());
            return ApiResponse.ok("获取成功", newMessages);
        } catch (Exception e) {
            log.error("获取新消息失败: topic=" + topic + ", lastId=" + lastId, e);
            return ApiResponse.error("获取失败: " + e.getMessage());
        }
    }

    /**
     * 获取历史消息接口
     */
    @GetMapping(value = "/messages/history")
    public ApiResponse getMessageHistory(@RequestParam String topic) {
        // 不限制已在线用户获取历史消息
        
        if (topic == null || topic.trim().isEmpty()) {
            return ApiResponse.error("topic参数不能为空");
        }
        
        try {
            List<Message> messages = new ArrayList<>();
            // 模拟从消息历史中获取历史消息
            // 实际项目中，这里应该从数据库或消息队列中查询
            for (Message message : MESSAGE_HISTORY) {
                if (message.getTopic().equals(topic)) {
                    // 过滤掉系统消息（用户上线/下线通知）
                    if (!isSystemNotificationMessage(message)) {
                        messages.add(message);
                    }
                }
            }
            
            return ApiResponse.ok("获取成功", messages);
        } catch (Exception e) {
            log.error("获取历史消息失败: {}", e.getMessage());
            return ApiResponse.error("获取历史消息失败");
        }
    }

    /**
     * 判断是否为系统通知消息（用户上线/下线）
     * @param message 消息对象
     * @return true表示是系统通知消息，false表示不是
     */
    private boolean isSystemNotificationMessage(Message message) {
        // 检查是否为系统发送的消息
        if ("system".equals(message.getMsgFrom())) {
            String content = message.getContent();
            // 检查是否包含用户离开聊天室的通知
            if (content != null && content.contains("离开了聊天室")) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获取系统监控信息接口
     */
    @GetMapping(value = "/system/info")
    public ApiResponse getSystemInfo() {
        try {
            if (serverMonitorService != null) {
                ServerMonitorService.SystemMonitorInfo info = serverMonitorService.getSystemMonitorInfo();
                return ApiResponse.ok("获取成功", info);
            } else {
                return ApiResponse.error("监控服务未启用");
            }
        } catch (Exception e) {
            log.error("获取系统监控信息失败", e);
            return ApiResponse.error("获取系统监控信息失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户IP信息接口
     */
    @GetMapping(value = "/ip-info")
    public ApiResponse getUserIPInfo(HttpServletRequest request) {
        try {
            // 获取用户真实IP地址
            String realIp = getClientIP(request);
            
            Map<String, String> ipInfo = new HashMap<>();
            ipInfo.put("ip", realIp);
            
            return ApiResponse.ok("获取成功", ipInfo);
        } catch (Exception e) {
            log.error("获取用户IP信息失败", e);
            return ApiResponse.error("获取用户IP信息失败: " + e.getMessage());
        }
    }
    
    /**
     * 获取客户端真实IP地址
     * @param request HttpServletRequest
     * @return 真实IP地址
     */
    private String getClientIP(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
            // 多个IP时取第一个
            if (ip.contains(",")) {
                ip = ip.split(",")[0];
            }
        } else {
            ip = request.getHeader("Proxy-Client-IP");
        }
        
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        
        // 处理IPv6本地回环地址
        if ("0:0:0:0:0:0:0:1".equals(ip)) {
            ip = "127.0.0.1";
        }
        
        return ip;
    }

    /**
     * 加入聊天室请求
     */
    public static class JoinRequest {
        private String userId;
        private String topic;
        private String province;

        // Getters and Setters
        public String getUserId() {
            return userId;
        }

        public void setUserId(String userId) {
            this.userId = userId;
        }

        public String getTopic() {
            return topic;
        }

        public void setTopic(String topic) {
            this.topic = topic;
        }

        public String getProvince() {
            return province;
        }

        public void setProvince(String province) {
            this.province = province;
        }
    }

    /**
     * API响应类
     */
    public static class ApiResponse {
        private boolean success;
        private String message;
        private Object data;
        private long timestamp;

        public ApiResponse(boolean success, String message, Object data) {
            this.success = success;
            this.message = message;
            this.data = data;
            this.timestamp = System.currentTimeMillis();
        }

        public static ApiResponse ok(String message, Object data) {
            return new ApiResponse(true, message, data);
        }

        public static ApiResponse error(String message) {
            return new ApiResponse(false, message, null);
        }

        // Getters
        public boolean isSuccess() {
            return success;
        }

        public String getMessage() {
            return message;
        }

        public Object getData() {
            return data;
        }

        public long getTimestamp() {
            return timestamp;
        }
    }

    // 添加定时任务用于清理不活动的用户
    @Scheduled(fixedRate = 300000) // 每5分钟执行一次
    public void cleanInactiveUsers() {
        try {
            long currentTime = System.currentTimeMillis();
            Iterator<Map.Entry<String, UserInfo>> iterator = USER_INFOS.entrySet().iterator();
            
            while (iterator.hasNext()) {
                Map.Entry<String, UserInfo> entry = iterator.next();
                UserInfo userInfo = entry.getValue();
                
                // 检查用户最近活动时间，如果超过5分钟没有活动，则移除
                long inactiveTime = currentTime - userInfo.getLastActivity().getTime();
                if (inactiveTime >= 5 * 60 * 1000) { // 5分钟
                    iterator.remove();
                    log.info("已清理不活动用户: userId={}, topic={}, inactiveTime={}ms", 
                            userInfo.getUserId(), userInfo.getTopic(), inactiveTime);
                }
            }
        } catch (Exception e) {
            log.error("清理不活动用户时发生错误", e);
        }
    }

    /**
     * 获取所有主题的在线用户列表（用于监控）
     */
    @GetMapping(value = "/monitor/online-users")
    public ApiResponse getOnlineUsersForMonitoring() {
        try {
            Map<String, List<UserInfo>> usersByTopic = new HashMap<>();
            
            // 按主题分组用户
            for (UserInfo userInfo : USER_INFOS.values()) {
                // 检查用户最近活动时间，如果超过5分钟没有活动，则认为不在线
                long inactiveTime = System.currentTimeMillis() - userInfo.getLastActivity().getTime();
                if (inactiveTime < 5 * 60 * 1000) { // 5分钟内有活动
                    String topic = userInfo.getTopic();
                    usersByTopic.computeIfAbsent(topic, k -> new ArrayList<>()).add(userInfo);
                }
            }
            
            return ApiResponse.ok("获取成功", usersByTopic);
        } catch (Exception e) {
            log.error("获取监控用在线用户列表失败", e);
            return ApiResponse.error("获取监控用在线用户列表失败: " + e.getMessage());
        }
    }
}